/* ========================================
 *
 * Copyright Nano IC, 2021-02-25
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF Nano IC.
 *
 * ========================================
*/
#include "one_wire_bus_phy.h"
#include "one_wire_bus_app.h"

#include "app_uart.h"

extern bool one_wire_bus_uart_send_one_packet(uint8_t *p_buf,uint16_t len);
extern uint16_t one_wire_bus_tra_read_queue_pack_uart_frame(void);


/**
 * @brief :控制物理层单总线时间片变量
 */
 
volatile uint32_t one_wire_bus_time_tick;

static volatile uint16_t one_wire_bus_time_slice;


static volatile uint16_t one_wire_bus_retransmit_time=0;
/**
 * @brief :时间片基准
 */
static volatile uint16_t one_wire_bus_time_slice_ref;

/**
 * @brief :控制物理层最多重传次数控制
 */
static volatile uint8_t one_wire_bus_phy_re_send_num;

/**
 * @brief :控制物理层最多重传次数控制
 */
static volatile uint8_t one_wire_bus_phy_re_send_num_ack;

/**
 * @brief :单总线物理层协议内部缓存，需要发送的长度
 */
static volatile uint16_t one_wire_bus_phy_send_len;

/**
 * @brief :单总线物理层协议内部缓存，需要发送的长度
 */
static volatile uint16_t one_wire_bus_phy_send_ack_len;

/**
 * @brief : 是否发送成功
 */
static volatile bool f_one_wire_bus_phy_send_ok;

/**
 * @brief :单总线物理层协议内部缓存
 */
uint8_t one_wire_bus_phy_rec_buf[ONE_WIRE_PHY_FRAME_REC_MAX_LENGTH];
/**
 * @brief :单总线物理层协议内部缓存
 */
uint8_t one_wire_bus_phy_send_buf[ONE_WIRE_PHY_FRAME_SEND_MAX_LENGTH];


/**
 * @brief :单总线物理层协议内部缓存
 */
uint8_t one_wire_bus_phy_re_send_buf[ONE_WIRE_PHY_FRAME_SEND_RE_LENGTH];

/**
 * @brief :单总线物理层协议初始化
 * 
 * @param 
 * @return true : 成功
 * @return false : 失败
 */
bool one_wire_bus_phy_init(void)
{
    one_wire_bus_time_slice = 0;
    one_wire_bus_phy_re_send_num = 0;
    one_wire_bus_phy_send_len = 0;
    f_one_wire_bus_phy_send_ok = true;
    one_wire_bus_time_slice_ref = (ONE_WIRE_BUS_PHY_SEND_INTERVAL*2) - 1;

    return true;
}

/**
 * @brief : 调用串口驱动，发送一个数据包
 *
 * @param p_buf: 要发送的数据指针
 * @param len: 要发送的数据长度
 * @return  true: 发送成功
 * @return  false: 发送失败
 */
bool one_wire_bus_phy_uart_send_one_packet(uint8_t *p_buf,uint16_t len)
{
    one_wire_bus_uart_send_one_packet(p_buf,len);
    return true;
}


/**
 * @brief : 调用串口驱动，发送一个数据包
 *
 * @param p_buf: 要发送的数据指针
 * @param len: 要发送的数据长度
 * @return  true: 发送成功
 * @return  false: 发送失败
 */
bool one_wire_bus_phy_uart_send_one_ack(uint8_t *p_buf)
{
	bool  ret=false;
	OneWirePacketStr *p_rec_packet = (OneWirePacketStr *)&p_buf[4];
    if(p_rec_packet->flag.needRenoteAck)
	{
		kb_ack_flag = 1;
		kb_ack_no_flag=0;
		ret=true;
	}
	if(p_rec_packet->flag.isAckmsg)
	{
		send_ack_flag = false;
	}
    return ret;
}
/** 
 * @brief 串口接一帧数据处理
 * @param p_uart_data ：串口接收数据指针
 * @param rec_len ： 串口接收到的数据长度
 * 
 * @return 数据不一样，说明Host下发的有指令，返回false
 * @return 数据一样，说明是自己发出的数据，返回true
 */
bool one_wire_bus_phy_rec_callback(uint8_t *p_uart_data,uint16_t rec_len)
{
	bool ret = false;
    memcpy(one_wire_bus_phy_rec_buf,p_uart_data,rec_len);
	if(memcmp(one_wire_bus_phy_rec_buf,one_wire_bus_phy_send_buf,one_wire_bus_phy_send_len) == 0 && one_wire_bus_phy_send_len>APP_UART_RX_HEAD_BACK_SIZE)
	{
		if(rec_len == one_wire_bus_phy_send_len)
		{
			ret = true;
		}
		one_wire_bus_phy_set_send_status(true);
	}
	one_wire_bus_time_slice = one_wire_bus_time_slice_ref;
    return ret;
}

/**
 * @brief 单总线动行时钟基准，系统需要每0.5mS调用一次本函数
 */
void one_wire_bus_phy_timer_tick_process_0_5ms(void)
{
//    if(one_wire_bus_time_slice > 0)
//    {  // 单总线时间片未到        
//        one_wire_bus_time_slice --;
//    }else
	if(uart_4ms_timer_flag)
    {        

        bool f_send_ok;
        one_wire_bus_time_slice_ref = (ONE_WIRE_BUS_PHY_SEND_INTERVAL*2) - 1;  // 默认7mS时间片
		
        /*
         *   1. PHY中数据发送成功；
         *   2. PHY中数据未发送成功，但重传次数超限；
         *   3. 满足1,2两种条件，就会申请新的数据发送；
         */
        f_send_ok = one_wire_bus_phy_get_send_status();
        if(f_send_ok == false)
        {  
	
			// PHY中数据未发送成功
			if(one_wire_bus_phy_re_send_num >= ONE_WIRE_BUS_PHY_MAX_RETRANS_NUM)
			{   // 重传次数超限，强制发送下一个包
				one_wire_bus_phy_set_send_status(true);
				one_wire_bus_phy_set_send_data_len(0x00);
				
			}
			else 
			{  // 重传上一帧数据
				uint16_t send_len;                
				send_len = one_wire_bus_phy_get_send_data_len();
				if(send_len > 0)
				{
					one_wire_bus_phy_uart_send_one_packet(one_wire_bus_phy_send_buf,send_len);
					one_wire_bus_phy_set_send_status(false);
				}
				one_wire_bus_phy_re_send_num ++;
				uart_4ms_timer_flag = false;
				uart_4ms_timer_tick=0;
				uart_500ms_timer_tick = 0;
			}
		
        }

        /*
         * 申请新数据发送
        */
        f_send_ok = one_wire_bus_phy_get_send_status();
        if(f_send_ok == true )
        {   // 上一帧数据全部发送成功，获取新的数据并发送
			if(!kb_ack_flag||send_ack_flag)
			{
				uint16_t new_data_len;            
				new_data_len = one_wire_bus_phy_obtain_new_data();
				if(new_data_len > 0)
				{  // 从队列中读取到数据
					one_wire_bus_phy_re_send_num = 0x00;
					one_wire_bus_phy_uart_send_one_packet(one_wire_bus_phy_send_buf,new_data_len);
//					one_wire_bus_phy_set_send_status(false);
					one_wire_bus_phy_set_send_status(true);
					bool ret = one_wire_bus_phy_uart_send_one_ack(one_wire_bus_phy_send_buf);
					
					/*
					 * 设置下一个时间片间隔
					*/
					one_wire_bus_time_slice = one_wire_bus_time_slice_ref;
					if(ret)
					{
						one_wire_bus_retransmit_time = (60)-1;
						one_wire_bus_phy_re_send_num_ack=0;
						if(new_data_len<ONE_WIRE_PHY_FRAME_SEND_RE_LENGTH)
						{
							one_wire_bus_phy_send_ack_len=new_data_len;
							memcpy(one_wire_bus_phy_re_send_buf,one_wire_bus_phy_send_buf,new_data_len);
//							printf("ack_updata = ");
//							console_log_num_byte(one_wire_bus_phy_re_send_buf,new_data_len);
						}
					}
					
	//				kb_serial++;
					uart_4ms_timer_flag = false;
					uart_4ms_timer_tick=0;
					uart_500ms_timer_tick = 0;
				}
			}else if(kb_ack_flag)
			{
				if(one_wire_bus_retransmit_time==0)
				{
					// PHY中数据未发送成功
					if(one_wire_bus_phy_re_send_num_ack >= ONE_WIRE_BUS_PHY_MAX_RETRANS_NUM)
					{   // 重传次数超限，强制发送下一个包
						one_wire_bus_phy_set_send_status(true);
						one_wire_bus_phy_set_send_data_len(0x00);
						kb_ack_flag=0;
						kb_ack_no_flag=1;
						rec_single_evt_test(MaintenanceServiceID,REMOTE_UART_SEND_STA,one_wire_bus_phy_send_buf[12],one_wire_bus_phy_send_buf[13],one_wire_bus_phy_send_buf[14]);
					}
					else {  // 重传上一帧数据
				
						if(one_wire_bus_phy_send_ack_len > 0)
						{
							memcpy(one_wire_bus_phy_send_buf,one_wire_bus_phy_re_send_buf,one_wire_bus_phy_send_ack_len);
							one_wire_bus_phy_uart_send_one_packet(one_wire_bus_phy_send_buf,one_wire_bus_phy_send_ack_len);
							one_wire_bus_phy_set_send_status(false);
//							printf("ret_updata = ");
//							console_log_num_byte(one_wire_bus_phy_send_buf,one_wire_bus_phy_send_ack_len);
						}
						one_wire_bus_phy_re_send_num_ack ++;
						one_wire_bus_retransmit_time = (60)-1;
					}
				}
			}
			
        }
    }
	
	if(one_wire_bus_retransmit_time>0)
	{
		one_wire_bus_retransmit_time--;
	}
	

	
} 

/**
 * @brief 计算一段数据的累加和
 * 
 * @param p_buf 输入数据缓冲
 * @param len 输入数据长度
 * @return uint8_t 累加和低8 Bit
 */
uint8_t one_wire_bus_get_buf_sum(uint8_t * p_buf,uint8_t len)
{
    uint32_t sum;

    sum = 0;
    for(uint8_t k=0;k<len;k++)
    {
        sum += p_buf[k];
    }
    return (sum & 0xff);
}

/**
 * @brief 根据标志位，判断串口一个包是否发送成功
 *
 * @return true: 成功
 * @return false: 失败
 */ 
bool one_wire_bus_phy_get_send_status(void)
{
uint32_t psr;
    bool flag;

    psr = csi_irq_save();
    flag = f_one_wire_bus_phy_send_ok;
    csi_irq_restore(psr);
    return flag;
}

/**
 * @brief 设置发送成功否标志
 *
 * @return 
 */ 
void one_wire_bus_phy_set_send_status(bool flag)
{
    uint32_t psr;
    psr = csi_irq_save();
    f_one_wire_bus_phy_send_ok = flag;
    if(flag)
    {  // 发送成功时，把长度设为零
        one_wire_bus_phy_send_len = 0x00;
    }
    csi_irq_restore(psr);
}

/**
 * @brief 获取要发送数据长度
 *
 * @return true: 成功
 * @return false: 失败
 */ 
uint16_t one_wire_bus_phy_get_send_data_len(void)
{
    uint32_t psr;
    uint16_t len;

    psr = csi_irq_save();
    len = one_wire_bus_phy_send_len;
    csi_irq_restore(psr);
    return len;
}

/**
 * @brief 设置要发送数据长度
 *
 * @return 
 */ 
void one_wire_bus_phy_set_send_data_len(uint16_t len)
{
    uint32_t psr;

    psr = csi_irq_save();
    one_wire_bus_phy_send_len = len;
    csi_irq_restore(psr);
}

/**
 * @brief 获取一帧新的数据
 *
 * @return uint16_t: 获取数据长度
 */ 
uint16_t one_wire_bus_phy_obtain_new_data(void)
{
    uint32_t psr;
    uint16_t frame_len;
    psr = csi_irq_save();    
    frame_len = one_wire_bus_tra_read_queue_pack_uart_frame();
    one_wire_bus_phy_send_len = frame_len;
    csi_irq_restore(psr);
    return frame_len;
}

bool one_wire_bus_phy_reportMap_process(uint8_t *p_data, uint8_t len)
{
    if(one_wire_bus_time_slice > 0)
    {  // 单总线时间片未到        
        one_wire_bus_time_slice --;
    }else
    {        
        uint16_t new_data_len;            
            new_data_len = one_wire_bus_phy_obtain_new_data();
        if(new_data_len == 0)
        {   // 队列是否为空
            
			one_wire_bus_phy_re_send_num = 0x00;
			one_wire_bus_phy_uart_send_one_packet(p_data,len);
			one_wire_bus_phy_set_send_status(false);
			/*
			 * 设置下一个时间片间隔
			*/
			one_wire_bus_time_slice = one_wire_bus_time_slice_ref;
			return true;
        }

    }
	 return false;
}
/* [] END OF FILE */
